import 'dart:convert';

import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:dmz/business/home/model/locus_data.dart';
import 'package:dmz/business/home/model/moto_search.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:math';

class EMIMapConfig {
  static const androidKey = "070345e7758f88076e2d1313f2992fc3";
  static const iosKey = "a321c58cda1c7bdddf214e1cf4ab65a5";
  static const webKey = "2f9d6c7971df854e207e5aaf2e239142";
}

class EMIMapManger {
  factory EMIMapManger() => _instance;

  static final EMIMapManger _instance = EMIMapManger._internal();

  EMIMapManger._internal() {
    init();
  }

  String? token;
  String? snCode;

  init() {}

  ///Google 坐标转换 高德
  Future<LatLng> convertLatLng(lng, lat) async {
    String apiKey = EMIMapConfig.webKey; // 请替换成您自己的高德地图API Key
    String url = 'https://restapi.amap.com/v3/assistant/coordinate/convert';

    String coords = '$lng,$lat';

    // 发送HTTP请求
    final response = await http
        .get(Uri.parse('$url?key=$apiKey&locations=$coords&coordsys=gps'));

    // 解析响应
    if (response.statusCode == 200) {
      Map<String, dynamic> data = jsonDecode(response.body);
      String str = data['locations'];
      List<String> datas = str.split(',');
      var latLng = LatLng(double.parse(datas[1]), double.parse(datas[0]));
      debugPrint('坐标转换 6666 --- $data');
      return latLng;
    } else {
      throw Exception('Failed to convert coordinates');
    }
  }

  /// 多个 Google 坐标转换 高德
  Future<List<LatLng>> convertMoreLatLng(List<Corrdinate> corrdinates) async {
    String apiKey = EMIMapConfig.webKey; // 请替换成您自己的高德地图API Key
    String url = 'https://restapi.amap.com/v3/assistant/coordinate/convert';

    List<LatLng> latlngs =
        corrdinates.map((e) => LatLng(e.lat!, e.lng!)).toList();

    List<LatLng> result = [];

    var chunDatas = chunkList(latlngs, 40);

    for (var i = 0; i < chunDatas.length; i++) {
      var element = chunDatas[i];
      String coords = '';
      for (var i = 0; i < element.length; i++) {
        if (i == 0) {
          coords = '${element[i].longitude},${element[i].latitude}';
        } else {
          coords = '$coords|${element[i].longitude},${element[i].latitude}';
        }
      }
      debugPrint('坐标转换 轨迹参数 --- $i  ');
      // 发送HTTP请求
      final response = await http
          .get(Uri.parse('$url?key=$apiKey&locations=$coords&coordsys=gps'));

      // 解析响应
      if (response.statusCode == 200) {
        Map<String, dynamic> data = jsonDecode(response.body);
        String str = data['locations'];
        List<String> datas = str.split(';');
        var dataeds = datas
            .map((e) => LatLng(
                double.parse(e.split(',')[1]), double.parse(e.split(',')[0])))
            .toList();
        // var latLng = LatLng(double.parse(datas[1]), double.parse(datas[0]));
        debugPrint('坐标转换9999 --- $i  ');
        result.addAll(dataeds);
      } else {
        throw Exception('Failed to convert coordinates');
      }
    }

    return result;
  }

  Future<List<LatLng>?> trajectoryCorrection(
      List<Corrdinate> corrdinates, List<LatLng> latLngs) async {
    String apiKey = EMIMapConfig.webKey; // 请替换成您自己的高德地图API Key
    String url = 'https://restapi.amap.com/v4/grasproad/driving';

    var datas = List.generate(
        corrdinates.length,
        (index) => {
              'x': latLngs[index].longitude,
              'y': latLngs[index].latitude,
              'ag': corrdinates[index].b,
              'tm': index == 0
                  ? corrdinates[index].t!
                  : corrdinates[index].t! - corrdinates[0].t!,
              'sp': corrdinates[index].s
            }).toList();

    // var streds = jsonEncode(datas);
    // debugPrint('坐标转换 纠偏0000 ---  --$streds');
    // Logger().d('坐标转换 纠偏11111 ---  --$streds');

    final response = await http.post(Uri.parse('$url?key=$apiKey'),
        headers: {'Content-Type': 'application/json'}, body: jsonEncode(datas));
    if (response.statusCode == 200) {
      Map<String, dynamic> data = jsonDecode(response.body);
      List<dynamic> points = data['data']['points'] ?? {};
      List removeed = [];
      if (points.isNotEmpty) {
        points.forEach((element) {
          if (element['y'] != null && !removeed.contains(element)) {
            // debugPrint('坐标转换 纠偏 555 ---${element['y']} ${element['x']}');
            removeed.add(element);
          }
        });
      }
      var result = List<LatLng>.generate(removeed.length,
          (index) => LatLng(removeed[index]['y'], removeed[index]['x']));
      // debugPrint(
      //     '坐标转换 纠偏 ---${removeed.length} ${data['data']['points'].length} --- $data');
      return result;
    } else {
      return null;
      // throw Exception('Failed to convert coordinates');
    }
  }

  List<List<T>> chunkList<T>(List<T> list, int chunkSize) {
    List<List<T>> chunks = [];
    for (var i = 0; i < list.length; i += chunkSize) {
      chunks.add(list.sublist(
          i, i + chunkSize > list.length ? list.length : i + chunkSize));
    }
    return chunks;
  }

  ///地理逆编码
  Future<Map<String, dynamic>> reverseGeocoding(LatLng latLnged) async {
    String apiKey = EMIMapConfig.webKey; // 请替换成您自己的高德地图API Key
    String url = 'https://restapi.amap.com/v3/geocode/regeo';
    String coords = '${latLnged.longitude},${latLnged.latitude}';

    // 发送HTTP请求
    final response = await http
        .get(Uri.parse('$url?key=$apiKey&location=$coords&radius=1000'));

    // 解析响应
    if (response.statusCode == 200) {
      Map<String, dynamic> data = jsonDecode(response.body);
      debugPrint('坐标转换 ---$data ${data['formatted_address']}');
      return data['regeocode'];
    } else {
      throw Exception('Failed to convert coordinates');
    }
  }

  ///地图搜索
  Future<List<SearchResult>> searchAddtrssWithString(
      String text, String city) async {
    // https://restapi.amap.com/v5/place/text?keywords=北京大学&types=141201&region=北京市&key=<用户的key>
    String apiKey = EMIMapConfig.webKey; // 请替换成您自己的高德地图API Key
    String url =
        'https://restapi.amap.com/v5/place/text?keywords=$text&key=$apiKey&region=$city';
    debugPrint('地图搜索url ---$url ');
    // 发送HTTP请求
    final response = await http.get(Uri.parse(url));

    // 解析响应
    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      debugPrint('地图搜索 ---$data ');
      if (data['pois'] != null) {
        return getSearchResult(data['pois']);
      } else {
        throw Exception('Failed to convert coordinates');
      }
    } else {
      throw Exception('Failed to convert coordinates');
    }
  }

  ///搜索结果处理
  List<SearchResult> getSearchResult(datas) {
    List<SearchResult> results = [];
    for (var element in datas) {
      SearchResult data = SearchResult();
      data.name = element['name'] ?? '';
      data.address =
          '${element['pname'] == element['cityname'] ? '' : element['pname']}${element['cityname']}${element['adname']}${element['address']}';
      data.name = element['name'] ?? '';
      var locations = ((element['location'] ?? '') as String).split(',');
      data.latitude = double.parse(locations[1]);
      data.longitude = double.parse(locations[0]);
      results.add(data);
    }
    return results;
  }

  double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    const R = 6371e3; // 地球半径，单位：米
    final phi1 = lat1 * pi / 180;
    final phi2 = lat2 * pi / 180;
    final deltaPhi = (lat2 - lat1) * pi / 180;
    final deltaLambda = (lon2 - lon1) * pi / 180;

    final a = sin(deltaPhi / 2) * sin(deltaPhi / 2) +
        cos(phi1) * cos(phi2) * sin(deltaLambda / 2) * sin(deltaLambda / 2);
    final c = 2 * atan2(sqrt(a), sqrt(1 - a));

    final distance = R * c; // 计算出的距离，单位：米
    return distance;
  }
}
